package com.ocm.core.service.impl;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.ocm.core.service.PropertyDefService;
import com.ocm.core.mapping.DTOService;
import com.ocm.core.mapping.DomainService;
import com.ocm.core.dao.PropertyDefDao;
import com.ocm.core.dao.StorageDao;
import com.ocm.core.domain.PropertyDefinition;
import com.ocm.core.domain.Storage;
import com.ocm.core.dto.PropertyDefinitionDto;
import com.ocm.core.helper.StorageHelper;

@Service("propertyDefService")
@Transactional(readOnly=true)
public class PropertyDefServiceImpl implements PropertyDefService {

   private PropertyDefDao propertyDefDao;

   private StorageDao storageDao;

   private DomainService domainService;

   private DTOService dtoService;

   @Autowired
   private StorageHelper storageHelper;
   
   @Autowired
   public PropertyDefServiceImpl(
      @Qualifier("storageDao")StorageDao storageDao,
      @Qualifier("propertyDefDao")PropertyDefDao propertyDefDao,
      @Qualifier("domainService")DomainService domainService,
      @Qualifier("dtoService")DTOService dtoService) {
      this.storageDao = storageDao;
      this.propertyDefDao = propertyDefDao;
      this.domainService = domainService;
      this.dtoService = dtoService;
   }

   @Transactional(readOnly=false, propagation=Propagation.REQUIRED)
   public void save(PropertyDefinitionDto propertyDefDto, Long storageId) {
      PropertyDefinition propertyDef = this.domainService.convertProperty(propertyDefDto);
      this.storageHelper.setUserInfo(propertyDef);
      Storage storage = storageDao.findById(storageId);
      propertyDef.setStorage(storage);
      this.propertyDefDao.save(propertyDef);
   }

   public List<PropertyDefinitionDto> findAll() {
      List<PropertyDefinition> propertyDefs = this.propertyDefDao.findAll();
      List<PropertyDefinitionDto> propertyDefDtos = this.dtoService.convertPropertyDtos(propertyDefs, null);
      return propertyDefDtos;
   }

   public PropertyDefinitionDto findId(Long propertyDefId) {
      PropertyDefinition propertyDef = this.propertyDefDao.findById(propertyDefId);
      PropertyDefinitionDto propertyDefDto = this.dtoService.convertPropertyDto(propertyDef, null);
      return propertyDefDto;
   }

   public boolean hasExistName(String propertyName, Long storageId) {
      PropertyDefinition propertyDefinition = this.propertyDefDao.findName(propertyName, storageId);
      if (propertyDefinition != null)
         return true;
      return false;
   }

   public List<PropertyDefinitionDto> findByIds(Long[] propertyDefIds) {
      List<PropertyDefinition> propertyDefs = this.propertyDefDao.findIds(propertyDefIds);
      List<PropertyDefinitionDto> propertyDefDtos = this.dtoService.convertPropertyDtos(propertyDefs, null);
      return propertyDefDtos;
   }

   public List<PropertyDefinitionDto> findAllFromStorageId(Long storageId) {
      List<PropertyDefinition> propertyDefs = this.propertyDefDao.findAllFromStorageId(storageId);
      List<PropertyDefinitionDto> propertyDefDtos = this.dtoService.convertPropertyDtos(propertyDefs, null);
      return propertyDefDtos;
   }

   public PropertyDefinitionDto findName(String propertyName, Long storageId) {
      PropertyDefinition propertyDefinition = this.propertyDefDao.findName(propertyName, storageId);
      PropertyDefinitionDto propertyDefDto = this.dtoService.convertPropertyDto(propertyDefinition, null);
      return propertyDefDto;
   }

   public List<PropertyDefinitionDto> findByNames(String[] propertyDefNames, Long storageId) {
      List<PropertyDefinition> propertyDefs = this.propertyDefDao.findNames(propertyDefNames, storageId);
      List<PropertyDefinitionDto> propertyDefDtos = this.dtoService.convertPropertyDtos(propertyDefs, null);
      return propertyDefDtos;
   }
}
